package com.gurumades.jsonform.server.forms.dispatch;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;

public class XMLResourceFormProvider implements FormProvider {

	private static String APPS_SAMPLE = "/WEB-INF/forms/";

	public XMLResourceFormProvider(String basePath) {
		XMLResourceFormProvider.APPS_SAMPLE = basePath;
	}

	public XMLResourceFormProvider() {
	}

	private List<String> managed_forms;

	ServletContext theContext;

	@Override
	public void setServletContext(ServletContext context) {
		this.theContext = context;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Set<String> getForms() {
		HashSet<String> set = new HashSet<String>();
		try {

			Set<String> resources = theContext.getResourcePaths(APPS_SAMPLE);
			for (String url : resources) {
				set.add(url.substring(APPS_SAMPLE.length(), url.length() - 4));
			}


			if (managed_forms != null) {
				set.addAll(managed_forms);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return set;
	}

	@Override
	public String getForm(String formID) {
		try {
			URL url = theContext.getResource(APPS_SAMPLE + formID + ".xml");
			InputStream streamResource = url.openStream();

			Unmarshaller marshaler = getUnMarshaller();
			JAXBElement o = (JAXBElement) marshaler
					.unmarshal(new InputStreamReader(streamResource));

			ObjectMapper mapper = new ObjectMapper();
			AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
			mapper.getDeserializationConfig().setAnnotationIntrospector(
					introspector);
			mapper.getSerializationConfig().setAnnotationIntrospector(
					introspector);

			String jsonString = mapper.defaultPrettyPrintingWriter()
					.writeValueAsString(o.getValue());

			return jsonString;

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JAXBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NullPointerException e) {
			e.printStackTrace();
		}
		return null;
	}

	private Unmarshaller getUnMarshaller() {
		try {

			JAXBContext cxt = initContext();
			return cxt.createUnmarshaller();
		} catch (JAXBException e) {
			e.printStackTrace();

			return null;
		}
	}

	private JAXBContext initContext() throws JAXBException {
		JAXBContext cxt = JAXBContext
				.newInstance("com.gurumades.jsonform.server.forms");
		return cxt;
	}

}
